package com.itita.ww2.utils.random;

import java.util.ArrayList;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;

import org.apache.commons.lang3.tuple.Pair;

import com.google.common.util.concurrent.AtomicLongMap;

/**
 * 随机权重选择器
 * @author NorthLan
 *
 * @param <K> 筛选列表
 * @param <V> 权重
 */
public class RandomSelector<K extends Object, V extends Number> {
	private TreeMap<Double, K> weightMap = new TreeMap<>();

	public RandomSelector(List<Pair<K, V>> list) {
		int size = list.size();
		for (int i = 0; i < size; ++i) {
			Pair<K, V> pair = list.get(i);
			double lastWeight = this.weightMap.size() == 0 ? 0 : this.weightMap.lastKey().doubleValue();
			this.weightMap.put(pair.getValue().doubleValue() + lastWeight, pair.getKey());
		}
	}

	/**
	 * 随机抽取一个
	 */
	public K random() {
		double randomWeight = this.weightMap.lastKey() * Math.random();
		SortedMap<Double, K> tailMap = this.weightMap.tailMap(randomWeight, false);
		return this.weightMap.get(tailMap.firstKey());
	}

	/**
	 * 随机抽取多个(多次)
	 * @param times 次数 
	 */
	public AtomicLongMap<K> randomMultiTimes(int times) {
		AtomicLongMap<K> ref = AtomicLongMap.create();
		for (int i = 0; i < times; ++i) {
			K k = random();
			ref.incrementAndGet(k);
		}
		return ref;
	}

	/**
	 * 随机抽取多个(多次)
	 * @param times 次数
	 */
	public List<K> randomMultiTimesAsList(int times) {
		List<K> ref = new ArrayList<>();
		for (int i = 0; i < times; ++i) {
			ref.add(random());
		}
		return ref;
	}

	/**
	 * 随机抽取多个(一次)
	 * @param count 个数
	 */
	public AtomicLongMap<K> randomMulti(int count) {
		AtomicLongMap<K> ref = AtomicLongMap.create();
		K k = random();
		for (int i = 0; i < count; ++i) {
			ref.incrementAndGet(k);
		}
		return ref;
	}

}
